package com.shengqin.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shengqin.common.pojo.CommonPage;
import com.shengqin.common.pojo.CommonResult;
import com.shengqin.entity.*;
import com.shengqin.mapper.PlanMapper;
import com.shengqin.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 体测计划 服务实现类
 * </p>
 *
 * @author Rui.Zhou
 * @since 2023-12-05
 */
@Service
public class PlanServiceImpl extends ServiceImpl<PlanMapper, Plan> implements IPlanService {

    @Resource
    private IPlanStudentService planStudentService;
    @Resource
    private IPlanRelationClassesService planRelationClassesService;
    @Resource
    private IUserService userService;
    @Resource
    private IScoreTemplateService templateService;
    @Resource
    private ISchoolService schoolService;

    @Override
    public Page<Plan> getPage(CommonPage<Plan> pageParam) {
        QueryWrapper<Plan> wrapper = new QueryWrapper<>();
        Plan planParam = pageParam.getQueryParam();
        if (StringUtils.hasLength(planParam.getName())) {
            wrapper.lambda().like(Plan::getName, planParam.getName());
        }
        if (StringUtils.hasLength(planParam.getCode())) {
            wrapper.lambda().eq(Plan::getCode, planParam.getCode());
        }
        if (planParam.getState() != null) {
            wrapper.lambda().eq(Plan::getState, planParam.getState());
        }
        if (planParam.getExamFlag() != null) {
            wrapper.lambda().eq(Plan::getExamFlag, planParam.getExamFlag());
        }
        String loginId = StpUtil.getLoginId().toString();

        User user = userService.getById(loginId);
        List<School> schools = schoolService.listByUserId(user.getId());
        if (CollectionUtils.isEmpty(schools)) {
            return new Page<>();
        }
        List<PlanRelationClasses> planRelationClassesList = planRelationClassesService.listBySchoolIds(schools.stream().map(s -> s.getId().toString()).collect(Collectors.toList()));
        if (CollectionUtils.isEmpty(planRelationClassesList)) {
            return new Page<>();
        }
        Set<Integer> planIds = planRelationClassesList.stream().map(PlanRelationClasses::getPlanId).collect(Collectors.toSet());

        wrapper.lambda().in(Plan::getId, planIds);
        wrapper.lambda().eq(Plan::getParentId, 0);
        wrapper.lambda().orderByDesc(Plan::getId);
        Page<Plan> planPage = new Page<>(pageParam.getPageNo(), pageParam.getPageSize());
        page(planPage, wrapper);
        buildRecords(planPage.getRecords());
        return planPage;
    }

    private void buildRecords(List<Plan> records) {
        if (!CollectionUtils.isEmpty(records)) {
            List<Integer> planIds = records.stream().map(Plan::getId).collect(Collectors.toList());
            List<Integer> scoreTemplateIds = records.stream().map(Plan::getTemplateId).collect(Collectors.toList());
            List<ScoreTemplate> templates = templateService.listByIds(scoreTemplateIds);
            List<Plan> childPlans = listByParentIds(planIds);
            Map<Integer, List<Plan>> childPlanMap = childPlans.stream().collect(Collectors.groupingBy(Plan::getParentId));
            records.forEach(record -> {
                templates.forEach(template -> {
                    if (record.getTemplateId().equals(template.getId())) {
                        record.setTemplateName(template.getName());
                    }
                });
                List<Plan> children = childPlanMap.getOrDefault(record.getId(), null);
                if (!CollectionUtils.isEmpty(children)) {
                    record.setChildPlans(children);
                }
            });
        }
    }

    private List<Plan> listByParentIds(List<Integer> planIds) {
        QueryWrapper<Plan> wrapper = new QueryWrapper<>();
        wrapper.lambda().in(Plan::getParentId, planIds);
        return list(wrapper);
    }

    @Override
    public Plan getByName(String name) {
        QueryWrapper<Plan> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(Plan::getName, name);
        return getOne(wrapper);
    }

    @Override
    public Plan getByCode(String planCode) {
        QueryWrapper<Plan> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(Plan::getCode, planCode);
        return getOne(wrapper);
    }

    @Override
    public Plan queryDetailById(Integer planId) {
        Plan plan = getById(planId);
        if (plan == null) {
            return null;
        }
        List<PlanRelationClasses> planRelationClassesList = planRelationClassesService.listByPlanId(plan.getId());
        List<String> selectClassesIds = new ArrayList<>();
        planRelationClassesList.forEach(planRelationClasses -> {
            selectClassesIds.add("classes_" + planRelationClasses.getClassesId());
        });
        plan.setSelectClassesList(selectClassesIds);
        List<Plan> plans = new ArrayList<>();
        plans.add(plan);
        buildRecords(plans);
        return plan;
    }
}
